#pragma once
#include "basic_component/common.hpp"
#include "basic_component/Socket.hpp"
#include "sys/epoll.h"


class reactor_server;//不要包Reactor_server.hpp, 否则就循环包含了, 该文件内没用到服务器, 声明其类型即可


class io_connection;
using io_func_t = std::function<std::string(std::string&)>;


//代表一条连接 -- 基类
class connection
{
protected:
    virtual void exception_handler() = 0;

public:
    connection(int sockfd = DEFAULT_FD, uint32_t event = 0)
    :_sockfd_ptr(std::make_unique<TCP_Socket>(sockfd))
    ,_events(event)
    ,_server(nullptr)//会在reactor_server::insert_connection()里设置, 所以在connection类家族里不要关心
    {}


    //设计成虚函数
    virtual void receive() = 0; //listen_socket和IO_socket在读数据时的区别即前者用accept, 后者用recv...

    virtual void send() = 0;//listen_connection用不到, 设为空方法即可

    int get_sockfd() const
    {
        return _sockfd_ptr->get_socket_fd();
    }

    uint32_t get_events() const
    {
        return _events;
    }

    void set_events(uint32_t events)
    {
        _events = events;
    }

    reactor_server* get_server() const
    {
        return _server;
    }

    void set_server(reactor_server* server)
    {
        _server = server;
    }

    void register_io_handle_func(const io_func_t& io_handle_func)
    {
        _io_handle_func = io_handle_func;
    }


protected:
    //1. sockfd
    std::unique_ptr<Socket> _sockfd_ptr;

    //2. 事件类型
    uint32_t _events;

    //3. 回指指针
    reactor_server* _server;

    //4. 回调函数 -- 进行数据报文的处理
    io_func_t _io_handle_func;//将数据(输入/输出缓冲区)从表示层递出, 交给上层(会话层)处理
    //缓冲区不是子类io_connection的成员吗? 这里我为什么要把回调函数放在基类?
    //因为io_connection的构造不暴露在外面, 都是由listen_connection在类内部创建的, 所以listen_connection需要知道回调函数是什么, 才能给io_connection初始化
};